Gerych, сюда тоже можно но вопрос будет закрыт через неделю с момента последнего ответа
ну а вообще для таких вещей стоит создать бложик и там в качестве ресурса подобное спрашивать
И в чём смысл делать глобалку, а не просто писать тогда уж сразу GetFilterUnit( )
Я сдеал локалку, чтобы вместо GetFilterUnit( ) писать то, что мне нужно, в данном случае CLONE quq_CCCP:
Потом клонов от способностей ищут не так,
Да так и я их могу найти
Точнее не совсем так, я их искал через Юнит входит в Область ( Игровая зона )
Но искать их в другом триггере и сдругим событием мне нафиг не нужно.
Мне нужно найти иллюзии сразу в триггере со способностью, чтобы потом не было геморроя
========================
И ещё раз повторюсь, что при повторном использовании способности, 2 прошлые иллюзии (да и вообще в принципе если рядом с гером будут другое любое ко-во иллюзий) перемещаются к противнику. Но две новосозданные остаются на месте.
Так же повторюсь, что когда проверка была IsUnitIllusion == false, то иллюзии определяло как не иллюзии!
Все кто пытались помочь, похоже проигнорировали это замечание...
========================
Мой вывод таков: Иллюзиям, призванным через стандартную Способность (Предмет: Иллюзии) присваивается статус иллюзий слегка позже, чем происходит проверка.
С другой стороны, скорее всего это может и можно как-то обойти, ведь есть карты примеры, где подобное работает нужным образом.
О том, как устроены чёртовы способности близов стоит только догадываться =\
К счастью Способность (Предмет: Иллюзии) не наносит 0.00 урона, и за это близам огромное спасибо (что у меня в очередной раз не бомбануло)
А вообще, проще по-моему сделать свою игру, чем нормальную карту в варкрафте -_-
у парня проблемы с алгоритмом, в какой вселенной 0.01 * 10 не 0.1?
В компьютерной. И да, 0.01 * 10 тоже может быть не равно 0.01 + ... + 0.01. Потому что складываются и умножаются real по-разному. Hate, надо просто использовать целочисленные, или пользоваться ==, в JASS == округляет числа для сравнения (!= не округляет).
Пороверил разные варианты, сразу упомяну, что с целочисленными всё огонь, просто какие-то другие воспоминания с ними всплывали. PT153, сначала не понял, зачем мне твоя строчка, она всего лишь выдавала 0.1 вместо 0.100, но тестировал разные варианты и всё прояснилось. Если задавать шаг 1.0, то всё исправно считается до 10.0, если задавать шаг 0.2, то всё считается до 2.2 и отображается ровно, но если сделать шаг 1.01, то вот тут и появляется то, ради чего ты эту строчку дал.
Именно с дробной частью косяк, и теперь не знаю как выбрать лучший ответ, по идее у тебя в каждом комментарии полезная информация. Просто объединил их в итоге.
Во втором триггере меняем Triggering (переключающий) (который в данном случае камень) на Attacking и все работает.
А, и еще событие не "получает урон" а "атакован"
Сергей4,
Перенесите hero = Атакующий до развилки IF/Then/Else
Вы пытаетесь посчитать ловкость от того, кого ещё нет, и уже после прока (которого нет, так как ловкость считывается из воздуха), вы присваиваете hero = атакующий герой.
Анимация кости базы при death сместилась у конечной точки в линейке анимации. Поправил. В игре потестил, работает. Рассчитать границы нужны когда делаешь новые или изменяешь старые анимации, одна из причин чтоб анимация не сместилась и была на своем месте. Но в твоем случае она сразу не помогла.
Увы но нет... Главная особенность той карты что все герои открываются по мере накопления очков за игру на карте, они не открыты сразу и не походу первой катки открываются а лишь с накоплением общих баллов. Я весь мозг сломал уже, в попытках вспомнить. Эх...
Если есть тимвиверные лаги, есть ещё миллион других программ для удалёнки, AnyDesk или Spleshtop (вроде платный, но это не проблема)
Но я делал по другому: по впн цеплялся домой на роутер, на домашнем компе на Win 10 pro создавал второго пользователя (в принципе можно и создавать и не патчить десятку под сервер), подключался через удалённый рабочий стол к домашнему компу и в принципе всё, vpn соедение на убунте хз где, но remmina для удалённого рабочего стола есть точно, ну или параллелс десктоп в режиме rdp.
Если ничего не понятно, то могу подробно расписать что и как я делал
Так же никто не отменял поставить варик на любой комп в рабочей сети (если есть доступ на такие пакости), хоть на компьютер бухглатера и в режиме второго пользователя сидеть по RDP на этом компе, WE вроде сильно не грузит =)
переименование w3m в w3x ничего не даст 1 ссылка с гугла xgm.guru/forum/showthread.php?t=33585
Есть такая вещь как защита карты, тут не помогут ни редакторы ни артмани, только деппротект, но при это ломается ГУИ структура, хотя в HOE такого и нет, карты уровня повыше, но в соло через артмани всё будет работать, как и "greedisgood 99999"
Как поменять тогда стартовое золото для игр с друзьями по сети? (надеюсь не по гаренке)
Попросить автора сделать для вас спец версию
Попросить депротекнуть карту и добавить золота умельцев, но у нас на XGM такое не любят
Но ведь сами по себе ошибки не происходят.
Причина подобного это А) - невнимательность либо твоя либо автора В) - программное обеспечение
Что бы в дальнейшем все было окей, просто сначала потести карту полностью что бы знать что и как должно быть, а потом вноси изменения, будь внимательней.
Еще советую связаться с автором и поговорить с ним об этой проблеме, или запросить у него еще 1 исходник да бы сверЯться с ним.
Вообще по идее диалоговое окно как бы фрейм, и он не должно дэсинхронизироваться от такого
Но всё можно ожидать от патча 1.26, но десинк возможен, если я токмо не ошибаюсь.
if GetLocalPlayer() == whichPlayer then
call DialogSetMessage(whichDialog, message)
endif
Если использовать локальную строку, то лучше создавать массив хранящий в себе строки, который должны показываться у игрока.
if GetLocalPlayer() == whichPlayer then
set s = message
else
set s = strData[ GetPlayerId( GetLocalPlayer() ) ]
endif
А если оставить тот метод со строкой, то есть шанс, что у другого пропадёт просто надпись-сообщение:
Если этот использовать.
if GetLocalPlayer() == whichPlayer then
set s = message
endif
ААААА, ты про декорации)
1 Это должна быть декорация (не разрушаемый объект)
2 минимальный и максимальный масштабы должны быть разными
3 ставишь декорацию выбираешь её и home\end увеличить\уменьшить ширину, pgup\pgdwn - увеличить\уменьшить высоту.
4 если именно X Y надо разные - открываешь свойства её и меняешь цифрами.
хоспаде, еле нашел
вам можно сказать повезло, там всё на простом джассе, + не забываем заглядывать в место для нестандартного кода, интересующие вас ф-ии это SX() и SY()
аналогично делаем для своих областей, в триггере инициализации я записываю в переменные значения координат игрового ректа, то же самое можно сделать с любой другой областью
управление w a d
*прочитал комменты*
если областей много, то всегда можно склеить из горизонтальных и вертикальных линий что-нибудь, из косых тоже можно, но там более геморно с событием выхода юнита из такой области.
Можно просто запоминать знак на каждом юните относительно каждой прямой, если он поменялся, значит юнит уже по другую сторону от прямой, мб ещё совместить это с системой чанков (и системой которая будет рассчитывать размер чанка относительно максимального радиуса действия спелла и размеров карты, для оптимальных размеров оного), но кому это нужно в вц3?
local location loc=GetUnitLoc(GetEnumUnit())
local location tcLoc=GetUnitLoc(udg_topot_caster)
local real a=AngleBetweenPoints(tcLoc, loc)
call SetUnitX(GetEnumUnit(),GetLocationX(loc) +CosBJ(a) * 10.00 )
call SetUnitY(GetEnumUnit(),GetLocationY(loc) +SinBJ(a) * 10.00 )
call RemoveLocation(tcLoc)
call RemoveLocation(loc)
set tcLoc=null
set loc=null
FabulousTiger, создаешь 12 х 12 абилок с разными координатами на карте команд, ну или меньше, все завивит от того что требуется и способность на основе Техника ('ANeg') и меняя уровень техники, ты свапаешь абилки и меняешь положение иконки на карте команд на ходу, изи но довольно громоздко.
Так же есть мемхак, но если вы задаёте такие вопросы явно рано о нем думать...
Это какие-то извращения у вас там.
Bj можно раскрыть и увидеть, что там происходит присваивание нового юнита глобалке bj_lastCreatedUnit.
Нужно сразу присваивать локалке нового юнита и не использовать эти ваши bj_lastCreatedUnit:
local unit u
u = CreateUnitAtLoc (GetTriggerPlayer(), 'hfoo', location, bj_UNIT_FACING)
Sergey105, цвет все правильно, было проблема это SetTextTagVelocity так как там у bj было еше 3 локальные данные для косинуса и углы... поэтому лишь поставил SetTextTagVelocityBJ и сработал....
вопервых ты в 1 и ту же ячейку пытаешся записать 2 значения (location и integer)
во вторых ты создаёш область по кординатам а следующей строчкой находиш эти же кординаты с помощью функций
в 3 ты сохранял точку в хэш и сразу же удалял её
и в 4 ты не инициализировал хэш
function Trig_SlayerUlt_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A00V'
endfunction
function Ultaction takes nothing returns nothing
local timer st = GetExpiredTimer()
local integer sid = GetHandleId(st)
local unit su = LoadUnitHandle (udg_Hash, sid, 0)
if IsUnitType(GetEnumUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitEnemy( GetEnumUnit(), GetOwningPlayer(su)) == true then
call UnitDamageTargetBJ( su, GetEnumUnit(), 210.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
endif
set su = null
endfunction
function UltimateRun takes nothing returns nothing
local timer st = GetExpiredTimer()
local integer sid = GetHandleId(st)
local unit su = LoadUnitHandle (udg_Hash, sid, 0)
local integer suid = GetHandleId(su)
local location suloc = LoadLocationHandle(udg_Hash, sid, 1)
local effect sueff = LoadEffectHandle (udg_Hash, sid, 2)
local real x = GetLocationX( suloc )
local real y = GetLocationY( suloc )
local rect surect = Rect( x - 600.00*0.5, y - 600.00*0.5, x + 600.00*0.5, y + 600.00*0.5 )
local location random = Location (GetRandomReal(x-600*.5,x+600*.5), GetRandomReal (y-600*.5, y+600*.5))
local integer sc = LoadInteger (udg_Hash, sid, 10)
call SetUnitPositionLoc( su, random )
call SetUnitAnimation( su, "attack" )
call AddSpecialEffectLocBJ( random, "Abilities\\Spells\\Human\\Thunderclap \\ThunderClapCaster.mdl" )
call DestroyEffectBJ ( GetLastCreatedEffectBJ() )
call AddSpecialEffectLocBJ( random, "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl" )
call DestroyEffectBJ ( GetLastCreatedEffectBJ() )
call ForGroupBJ ( GetUnitsInRangeOfLocAll(250.00, suloc), function Ultaction )
set bj_wantDestroyGroup=true
call SaveInteger(udg_Hash,sid,10,sc + 1)
if sc >= 10 then
call SetUnitPositionLoc( su, suloc )
call DestroyEffectBJ( sueff )
call SetUnitPathing( su, true )
call SetUnitInvulnerable( su, false )
call PauseUnitBJ( false, su )
call SetUnitVertexColorBJ( su, 100, 100, 100, 0.00 )
call PauseTimer(st)
call DestroyTimer(st)
call FlushChildHashtable(udg_Hash, sid)
endif
set suloc = null
set random = null
set st = null
set su = null
set sueff = null
endfunction
function Trig_SlayerUlt_Actions takes nothing returns nothing
local timer st = CreateTimer()
local integer sid = GetHandleId(st)
local unit su = GetTriggerUnit()
local integer suid = GetHandleId(su)
local location suloc = GetUnitLoc(su)
local effect sueff
local real x=GetUnitX(su)
local real y=GetUnitY(su)
call AddSpecialEffectTargetUnitBJ ( "hand right", su, "Abilities\\Weapons \\PhoenixMissile\\Phoenix_Missile.mdl" )
set sueff = GetLastCreatedEffectBJ()
call SetUnitPathing( su, false )
call SetUnitInvulnerable( su, true )
call PauseUnitBJ( true, su )
call SetUnitVertexColorBJ( su, 100, 100, 100, 50.00 )
call SaveUnitHandle(udg_Hash, sid, 0, su)
call SaveAgentHandle(udg_Hash, sid, 1, suloc)
call SaveAgentHandle(udg_Hash, sid, 2, sueff)
call SaveAgentHandle(udg_Hash, suid, 0, st)
call SaveInteger (udg_Hash, sid, 10, 1)
call TimerStart( st, .3, true, function UltimateRun )
set suloc = null
set st = null
set su = null
set sueff = null
endfunction
===========================================================================
function InitTrig_SlayerUlt takes nothing returns nothing
set gg_trg_SlayerUlt = CreateTrigger ( )
set udg_Hash=InitHashtable()
call TriggerRegisterAnyUnitEventBJ ( gg_trg_SlayerUlt, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition ( gg_trg_SlayerUlt, Condition( function Trig_SlayerUlt_Conditions ) )
call TriggerAddAction ( gg_trg_SlayerUlt, function Trig_SlayerUlt_Actions )
endfunction
filterGetUnitsOfTypeIdAll - фильтр, вместо него должно быть написано либо null или Condition( function XXX) Короче зачем нужен фильтр? Фильтр при выборе всех юнитов сразу отсеивает не нужных, если по условию не подходит, то выкидывает.. Вам сразу достается готовая группа с нужными юнитами
А в качестве переменных используй GetFilterUnit, GetFilterPlayer. На гуи по-другому называют MatchingUnit
где XXX - название функции, эта функция возвращает boolean (то есть истину или ложь)
вбей в поиск названии функции, может найдешь ответ
например выделяем все здания UNIT_TYPE_STRUCTURE, а те, кто не является зданием отсеиваем
function XXX takes nothing returns boolean
return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction
насчет статьи не видел, это придет с пониманием. Главное начать. Сначала тупо конверт, и оптимизация. А дальше можешь сам
что у тебя там не работает скидывай сюда
Bornikkeny, сделал специально чтобы доказать тебе что ты несёшь бред
даже 2 скрина приложил
думаю закинуть библиотеки сможешь сам (в папку *твой jngp*\AdicHelper\lib)
Хорошо группы реализуешь как альтернативу unit[array]. Я тоже самое получил. nvc123, и всё же твой хук не тот что мне нужен.
Я решил проблему, спасибо что дал идею обрабатывать движение внутри структуры, а не в стеке.
кот
library Hook initializer Init_Hook uses LibMath
globals
mhook ahook[100]
integer ihook = -1
endglobals
struct mhook
unit host = null
unit target = null
real face = 0
real speed = 0
real dis = 0
real dismax = 0
integer chaini = 0
unit chain[50]
real scale = 0
integer move = 1
integer i = 0
static method Create takes unit host, real tx, real ty, real scale returns mhook
local mhook h = mhook.create()
local integer i = GetPlayerId(GetOwningPlayer(host))
local real x = GetUnitX(host)
local real y = GetUnitY(host)
local real f = GetAngleXY(x,y,tx,ty)
set h.host = host
set h.face = f
set h.speed = 600
set h.dismax = 1400
set h.scale = scale
set h.chain[0] = CreateUnit(Player(i),'h007',GetPolarX(GetUnitX(host),f,h.scale/2),GetPolarY(GetUnitY(host),f,h.scale/2),f)
set h.i = i
call UnitAddAbility(h.chain[0],'Amrf')
call UnitAddAbility(h.chain[0],'Amrf')
call SetUnitFlyHeight(h.chain[0],50,0)
call SetUnitPathing(h.chain[0],false)
return h
endmethod
method Start takes nothing returns boolean
if ihook < 1000 then
set ihook = ihook + 1
set ahook[ihook] = this
return true
else
return false
endif
endmethod
method Destroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i > ihook
if ahook[i] == this then
set ahook[i] = ahook[ihook]
set ahook[ihook] = 0
set ihook = ihook - 1
set i = ihook // выход из цикла
endif
set i = i + 1
endloop
set this.target = null
set this.host = null
call this.destroy()
endmethod
method Move takes nothing returns nothing
local integer i1 = 0
local integer l = 0
local real x
local real y
local real xh
local real yh
local real f
if move == 1
set dis = dis + speed*0.025
loop
exitwhen i1 > .chaini
set x = GetUnitX(.chain[i1])
set y = GetUnitY(.chain[i1])
if i1 > 0 then
set f = GetAngleXY(x,y,GetUnitX(.chain[i1-1]),GetUnitY(.chain[i1-1]))
call SetUnitX(.chain[i1],GetPolarX(x,f,.speed*0.025))
call SetUnitY(.chain[i1],GetPolarY(y,f,.speed*0.025))
else
set f = face
call SetUnitX(chain[i1],GetPolarX(x,f,.speed*0.025))
call SetUnitY(chain[i1],GetPolarY(y,f,.speed*0.025))
endif
call SetUnitFacing(chain[i1],f)
set i1 = i1 + 1
endloop
set x = GetUnitX(chain[chaini])
set y = GetUnitY(chain[chaini])
set f = GetAngleXY(GetUnitX(.host),GetUnitY(.host),x,y)
set xh = GetPolarX(GetUnitX(.host),f,.scale/2)
set yh = GetPolarY(GetUnitY(.host),f,.scale/2)
//Create==================
if GetDisXY(xh,yh,x,y) >= .scale/2 then
set chaini = chaini + 1
set chain[chaini] = CreateUnit(Player(.i),'h007',xh,yh,f)
call UnitAddAbility(.chain[.chaini],'Amrf')
call UnitAddAbility(.chain[.chaini],'Amrf')
call SetUnitFlyHeight(.chain[.chaini],50,0)
endif
if dis > dismax then
set move = 0
endif
else
//REVERSE=============
set xh = GetUnitX(host)
set yh = GetUnitY(host)
set chain[chaini+1] = host
loop
exitwhen l > chaini
set x = GetUnitX(chain[l])
set y = GetUnitY(chain[l])
//if chain[chaini] == null then
// set f = GetAngleXY()
//endif
set f = GetAngleXY(x,y,GetUnitX(chain[l+1]),GetUnitY(chain[l+1]))
call SetUnitX(chain[l],GetPolarX(x,f,speed*0.025))
call SetUnitY(chain[l],GetPolarY(y,f,speed*0.025))
call SetUnitFacing(chain[l],f-180)
set l = l + 1
endloop
//Destroy==================
set x = GetUnitX(chain[chaini])
set y = GetUnitY(chain[chaini])
set xh = GetUnitX(host)
set yh = GetUnitY(host)
if GetDisXY(GetUnitX(chain[chaini]),GetUnitY(chain[chaini]),GetUnitX(host),GetUnitY(host)) < 100 then
call RemoveUnit(chain[chaini])
set chain[chaini] = null
set chaini = chaini - 1
if chaini == -1 then
call .Destroy()
endif
endif
endif
endmethod
endstruct
private function Engine takes nothing returns nothing
local integer i = 0
local mhook h
local group g
local unit t
loop
exitwhen i > ihook
if ahook[i] != 0 then
set h = ahook[i]
//--run--//
call h.Move()
else
set ahook[i] = ahook[ihook]
set ahook[ihook] = 0
set ihook = ihook - 1
set i = i - 1
endif
set i = i + 1
endloop
//call DestroyGroup(g)
set g = null
set t = null
endfunction
function Trig_HookC_Bool takes nothing returns boolean
if GetSpellAbilityId() == 'A01D' then //Способность Мясной хук
return true
else
return false
endif
endfunction
function Trig_HookC_Actions takes nothing returns nothing
local mhook h
set h = mhook.Create(GetSpellAbilityUnit(),GetSpellTargetX(),GetSpellTargetY(),110)
call h.Start()
endfunction
function Init_Hook takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction( t, function Trig_HookC_Actions )
call TriggerAddCondition(t,function Trig_HookC_Bool)
call TimerStart(CreateTimer(),0.025,true,function Engine)
endfunction
endlibrary
Было создано 22 366 679 экземпляров класса CUnitListNode, которые заняли 255.9 МБ памяти.
При очередной попытке выделения, игра упала.
Виной всему утечки памяти: за 21 минуту набралось 80 тысяч групп и 20 тысяч точек.
Также, из-за выполнения большого количества кода, сильно лагает.
На стадии выбора героя (первые две минуты), выполняется 550 000 операций в секунду, а далее — 1 200 000.
Для сравнения: лимит потока — 300 000 операций.
Хорошо, что ты приложил карту, так как в логе маловато информации.
nvc123, увы там дефолт ИИ, недаст особо управлять мобами.
Щяс скину пример из доты но более понятный, как заставить нейтралов ходить и атаковать.
Вот вам пример контроля нейтралами.
У меня было однажды нечто похожее с нестандартным зданием. Так как ошибку найти не удалось (ну нет нифига там, даже код не начинал писать ещё), я списал всё на рандомный баг редактора и удалил здание, а затем пересоздал.
И в чём смысл делать глобалку, а не просто писать тогда уж сразу GetFilterUnit( )
Я сдеал локалку, чтобы вместо GetFilterUnit( ) писать то, что мне нужно, в данном случае CLONE quq_CCCP:
Потом клонов от способностей ищут не так,
Да так и я их могу найти
Точнее не совсем так, я их искал через Юнит входит в Область ( Игровая зона )
Но искать их в другом триггере и сдругим событием мне нафиг не нужно.
Мне нужно найти иллюзии сразу в триггере со способностью, чтобы потом не было геморроя
========================
И ещё раз повторюсь, что при повторном использовании способности, 2 прошлые иллюзии (да и вообще в принципе если рядом с гером будут другое любое ко-во иллюзий) перемещаются к противнику. Но две новосозданные остаются на месте.
Так же повторюсь, что когда проверка была IsUnitIllusion == false, то иллюзии определяло как не иллюзии!
Все кто пытались помочь, похоже проигнорировали это замечание...
========================
Мой вывод таков: Иллюзиям, призванным через стандартную Способность (Предмет: Иллюзии) присваивается статус иллюзий слегка позже, чем происходит проверка.
С другой стороны, скорее всего это может и можно как-то обойти, ведь есть карты примеры, где подобное работает нужным образом.
О том, как устроены чёртовы способности близов стоит только догадываться =\
К счастью Способность (Предмет: Иллюзии) не наносит 0.00 урона, и за это близам огромное спасибо (что у меня в очередной раз не бомбануло)
А вообще, проще по-моему сделать свою игру, чем нормальную карту в варкрафте -_-
у каждого формата свой алгоритм,вот из за этого такая разница ,особенно на вес блп влияет прозрачность что лутше прозрачные места которые не затрагивает меш красить чёрным цветом
Пока что не стоит. Значимых предпосылок к тому что все игроки переберутся на официальные сервера пока нет.
Однако учитывать возможности и ограничения новых патчей стоит. Мы придерживаемся такого направления пока, сейчас разрабатываем под 26а.
Ну, всё))) Бутылка прошла мимо тебя))) Решение пришло само собой - скачал тестовый американский варик и там п оумолчанию выставил оразрешение 1280х960, плюс там было окошко с возможностью растянуть экран по контуру. При проверке разрешения экрана выяснилось, что русский варик соответствует тому разрешению которое выставляет видюха. Тупо поменял разрешение рабочего стола на 1280х960 и всё пошло (в настройках варика автоматом стало такое же).
Событие - герой входит в нужную область
Действие - Kill такой-то unit
Если нужно не какого-то конкретного, то определение позиции героя, выделять в группу нужных юнитов на нужном расстоянии и выбирать случайного из них и kill его. В идеале безутечно с обнулением переменных.
В чём проблемы?
Я знаю только один способ избавления от утечек - писать код без них.Тебе нужен кто-то знающий игровые скрипты или злосчастный Jass. Иначе уровень неопределённости вопроса не позволит подсказать что-то дельное.
bOrissko, зоны достаточно крупные, идут в центр области
Просто сделал такую же систему и некоторые тупили и стояли на месте, но стоило сделать точку приказа, чуть дальше от границы области (по которой идет проверка, зашли или нет) и поменять с рандомной точки до центра и они перестали останавливаться.
Дик, переменную можно скормить этому триггеру через JASS или Lua, но событие запишется на основании значения переменной на момент добавления события - можно сколько угодно менять переменную после этого, но триггер будет работать только на того юнита который был записан в переменную на момент когда добавлялось событие. Возможно действие "добавить событие к триггеру" в ГУИ тоже так умеет.
Если абуза боишься, можно просто поставить, что пассивка не действует чаще, например, раза в 0.5 секунды (таймером вешаешь на юнита "что-то" - абилу-маркер, хэш-значение и т. д., после окончания таймера убираешь, а в условиях - если у юнита это "что-то" есть, то пассивка не канает)
Filius Dei, так что-то не так делаешь. Функцию нельзя внутри функции копировать, функцию закинь повыше.
знаешь такую находил много раз. атака сзади атака в спину и др. ищи на форуме "заклинание на заказ", там в первых наработках есть похожее. Углы сложно подсчитать?
подробности
Я тебе скинул пример, на событие юнит атакован. Но ты должен знать что "юнит атакован" - событие, при котором юнит начинает замахиваться, а потом пускает снаряды (у милишников без этого), и потом происходит урон. Надо делать систему урона от события "юнит получает урон". Так как при событии "юнит атакован" можно промахнуться.
Когда при событии "получает урон" наносишь дополнительный триггерный урон, смотри, чтобы зацикливания не было.
на экран выводят отладочные сообщение. Когда триггер срабатывает, ты об этом не знаешь. Ты не видишь этого, тк все действия внутри игры. А сработал ли триггер, мб вообще не работает (пример забыл включить триггер)? Поэтому выводят на экран. Или другая ситуация: почему то условие не работает, проверяем прокатило ли условие: тоже самое в блоке условия вставляют действие вывода сообщения игроку.
if b then //если условие b прокатило
выводим сообщение "прокатило условие b"
else //иначе
выводим сообщение "условие b не прокатило" //будем знать что триггер хоть работает
endif
будем знать что условия прокатывает или нет. Мб у вас условие багованное, один раз на jass такое написал, обрывалось или не работало. Сообщение никакого не выводило.
Или допустим нужно знать какие числа или строки у вас, как считает, считает ли вообще? тоже выводишь на экран результат строки или число
где его взять
в триггере в действии в разделе "игра" можно сообщение выводить
так можешь еще проверять переменные вариковские. например, если не знаешь что за переменная. скажем какой юнит хранится под этой переменной как trigger unit. выводи имя юнита на экран, выведут название типа например "пехотинец", который вызвал каст (будешь знать что вызвал футман а не бугай. И значит trigger unit - кастер итд). про потоки это мой анализ, но как бы локалки делай как в статье про локи, это с опытом придет
Дальше пришла в голову другая идея. Думаю, можно сделать с помощью ремонта зданий Альянса: на месте смерти героя создаётся здание с моделью креста со здоровьем 1/100 ед., а союзные герои ремонтируя крест будут повышать её здоровье, получается некая иллюзия прогресс бара. И если спрятать способность ремонта с помощью функции HideAbilityButton( ) из мемхака, то будет ли она срабатывать при нажатии на ПКМ? Также, как отловить момент полного ремонта здания? С помощью таймера проверять процент здоровья каждые доли секунды?
раскрыть
scope HeroRevive initializer Initialization
struct herorevive
private unit dyingUnit
private unit reincarnate
private real life
private thistype prev
private thistype next
public static constant trigger trig = CreateTrigger( )
public static constant timer period = CreateTimer( )
private static method iterate takes nothing returns nothing
local thistype this = thistype( 0 ).next
loop
exitwhen ( this == 0 )
if ( GetWidgetLife( this.reincarnate ) > this.life ) then
set this.life = GetWidgetLife( this.reincarnate )
elseif ( GetWidgetLife( this.reincarnate ) >= GetUnitState( this.reincarnate, UNIT_STATE_MAX_LIFE ) ) then
call ReviveHero( this.dyingUnit, GetUnitX( this.dyingUnit ), GetUnitY( this.dyingUnit ), true )
call RemoveUnit( this.reincarnate )
set this.reincarnate = null
set this.life = 0.0
set this.prev.next = this.next
set this.next.prev = this.prev
if ( thistype( 0 ).next == 0 ) then
call PauseTimer( thistype.period )
endif
call thistype.deallocate( this )
elseif ( GetWidgetLife( this.reincarnate ) <= this.life ) then
set this.life = 1.0
call SetWidgetLife( this.reincarnate, this.life )
endif
set this = this.next
endloop
endmethod
public static method actions takes nothing returns nothing
local thistype this = thistype.allocate( )
set this.next = 0
set this.prev = thistype( 0 ).prev
set this.next.prev = this
set this.prev.next = this
set this.dyingUnit = GetDyingUnit( )
set this.reincarnate = CreateUnit( GetOwningPlayer( this.dyingUnit ), 'h003', GetUnitX( this.dyingUnit ), GetUnitY( this.dyingUnit ), 0.0 )
set this.life = 1.0
call SetUnitPathing( this.reincarnate, false )
call SetWidgetLife( this.reincarnate, this.life )
if ( this.prev == 0 ) then
call TimerStart( thistype.period, 0.10, true, function thistype.iterate )
endif
endmethod
public static constant method conditions takes nothing returns boolean
return IsUnitType( GetDyingUnit( ), UNIT_TYPE_HERO )
endmethod
endstruct
public function Initialization takes nothing returns nothing
call TriggerRegisterPlayerUnitEvent( herorevive.trig, Player( 1 ), EVENT_PLAYER_UNIT_DEATH, null )
call TriggerRegisterPlayerUnitEvent( herorevive.trig, Player( 2 ), EVENT_PLAYER_UNIT_DEATH, null )
call TriggerRegisterPlayerUnitEvent( herorevive.trig, Player( 3 ), EVENT_PLAYER_UNIT_DEATH, null )
call TriggerRegisterPlayerUnitEvent( herorevive.trig, Player( 4 ), EVENT_PLAYER_UNIT_DEATH, null )
call TriggerAddCondition( herorevive.trig, Condition( function herorevive.conditions ) )
call TriggerAddAction( herorevive.trig, function herorevive.actions )
endfunction
endscope
Вот только если спрятать кнопку через HideAbilityButton( ), то способность ремонта зданий исчезает и не работает через ПКМ.
Да у тебя куча дыр, во-первых ты не запустил триггер 115 области lumber direction, и оно соответственно не реагирует на событие. Во-вторых перепроверь gold проверку условия на да или нет в той карте которую ты отправил стоит нет
А золото не движется потому что ты ожидание 0,5 сек поставил а область в милисекунде от изначальной то есть триггер не успевает запуститься
невозможно.
Только если обрабатывать всю информацию вручную.
Кинули лечилку - прибавить 40, повешали регенерацию хуска - проверить уровень способности, добавить. Постоянно проверять на ауры регена, полученные баффы и их уровень.
Аура смерти действует не в процентах, а в фиксированных числах. А нужно в процентах.
Аура Смерти (Unholy Aura) ['AUau'] - даёт бонус к регенерации здоровья (чистым значением) и бонус к скорость передвижения юнита (в процентах).
Регенерация здоровья никак не зависит от того, какая и сколько регенерации у юнита. Она просто даёт +N (или минус, если трицательное) к его ежесекундному показателю. Это значение не усиливается и не ослабляется чем-либо (лишь складывается). При этом там есть параметр Процент повышения (Uau3), который превращает указанное число в множитель на текущее в данный момент максимальное здоровье юнита (у героев макс.ХП изменяется с течением игры, это имеется ввиду).
Зачем делать сон аурами, которые не складываются, дак еще и их бафф не удаляется и юниты могут регенится по 2-4 сек свыше того момента как исчезла аура.
Создаем триггер с переодическим событием, скажем 0.25 сек или 0.5, и группу, в которой всем юнитам восстанавливаем % хп исходя из уровня баффа сна, если у юнита нет баффа сна, удаляем его из группы, и еще 1 триггер который срабатывает на каст сна, и заносит спящего в группу регенерации. Легко, просто, полностью кастомный реген который ни с чем не багует.
проведя еще пару часов за тестами, в голову пришла мысль о фаталках из-за большого числа юнитов на мелководье
остановился на том, что ошибка вылетела из-за случайных точек спауна по квадрату на мелко-глубкоководной местности. сделал спаун в отдельных мини областях - ошибка исчезла
» WarCraft 3 / Нужно сделать захват точки или здания
» WarCraft 3 / Что то не хочет работать
» WarCraft 3 / Проблема с дропом
» WarCraft 3 / Assets
» WarCraft 3 / урон от ловкости
» WarCraft 3 / Что я забыл?
» WarCraft 3 / не импортируются файлы (JNGP)
» WarCraft 3 / Localized strings
» WarCraft 3 / x y?
» WarCraft 3 / bj ?
» WarCraft 3 / Прозрачные декорации
» WarCraft 3 / Кастомные фреймы
» WarCraft 3 / GetLocationZ
» WarCraft 3 / Вылетает карта
» WarCraft 3 / Я пикаю,а они не пикаются
» WarCraft 3 / Перевод карты.
» WarCraft 3 / Патч 1.29
» WarCraft 3 / юнит вошёл в область
» WarCraft 3 / BlzUnitHideAbility
» WarCraft 3 / Как сделать атаку у героя/юнита 0 - 0?
» WarCraft 3 / Не могу разобраться
» WarCraft 3 / Как отловить смерть героев с крестом воскрешения?
» WarCraft 3 / Помогите разобраться в триггерах карты
» WarCraft 3 / Реген
» WarCraft 3 / Фатальная ошибка, связанная с картой